package Beans;
import frame.MainFrame;

import java.util.List;
import java.util.Queue;

public class SchedulingMethods {
    /**
    * @Description: 从数据库中获取进程
    * @Param: [Newqueue]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void insertNewFromDB(Queue<PCB> Newqueue) {
        PCBDAO dao = new PCBDAO();
        List<PCB> PCBlist = dao.findAllPCB();
        for (PCB pcb : PCBlist) {
            pcb.setTimeWait(0);
            Newqueue.offer(pcb);
        }
    }

    /**
    * @Description: 按照优先级快速排序
    * @Param: [pcbs, low, high]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void sort(PCB[] pcbs, int low, int high) {

            if (low < high) {
                int index = getIndex(pcbs, low, high);
                sort(pcbs, low, index - 1);
                sort(pcbs, index + 1, high);
            }

    }

    /**
    * @Description: 按照优先级快速排序--找到中间值
    * @Param: [pcbs, low, high]
    * @return: int
    * @Author: PY
    * @Date: 2021/11/26
    */
    private static int getIndex(PCB[] pcbs, int low, int high) {
        PCB tmp = pcbs[low];
        while (low < high) {
            while (low < high && pcbs[high].getPriority() >= tmp.getPriority()) {
                high--;
            }
            pcbs[low] = pcbs[high];
            while (low < high && pcbs[low].getPriority() <= tmp.getPriority()) {
                low++;
            }
            pcbs[high] = pcbs[low];
        }
        pcbs[low] = tmp;
        return low;
    }

    /**
    * @Description: 添加进程到running队列中
    * @Param: [pcbs, Runningqueue]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void insertToRunning(PCB[] pcbs, Queue<PCB> Runningqueue) {
        if (Runningqueue.peek() == null) {
            Runningqueue.offer(pcbs[0]);
            pcbs[0] = null;
            for (int i = 0; i < pcbs.length - 1; i++) {
                if (i == pcbs.length) {
                    pcbs[i] = null;
                    break;
                }
                pcbs[i] = pcbs[i + 1];
            }
        }
        pcbs[pcbs.length - 1] = null;
    }

    /**
    * @Description: 运行进程
    * @Param: [RunningQueue, terminatedQueue, readyQueue]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void runProcess(Queue<PCB> RunningQueue, Queue<PCB> terminatedQueue, PCB[] readyQueue) {
        PCB runningProcess = RunningQueue.remove();
        if(runningProcess!=null) {
            int timeRequired = runningProcess.getTimeRequired();
            System.out.println("正在运行进程：" + runningProcess.getPid());
            try {
                for (int i = 0; i < timeRequired; i++) {
                    Thread.sleep(1000);
                    if (runningProcess.getPriority() != 0)
                        runningProcess.setPriority(runningProcess.getPriority() - 1);
                    for (PCB pcb : readyQueue) {
                        if (pcb != null) {
                            pcb.setTimeWait(pcb.getTimeWait() + 1);
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("进程运行完毕，耗时" + runningProcess.getTimeRequired());
            terminatedQueue.offer(runningProcess);
            StorageMethods.removeFromMemory(runningProcess,MainFrame.mainMemories);
        }
    }

    /**
    * @Description: 添加进程到ready队列中
    * @Param: [readyQueue, queue]
    * @return: boolean
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static boolean insertToReady(PCB[] readyQueue, Queue<PCB> queue) {
        boolean Success = false;
        int count = 0;
        for (int i = 0; i < readyQueue.length; i++) {
            if (readyQueue[i] == null && !queue.isEmpty()) {
                boolean success = false;
                while (!success) {
                    count++;
                    success = StorageMethods.insertToMemory(queue.peek(), MainFrame.mainMemories);
                    Success = success;
                    if (count >= 10) {
                        break;
                    }
                }
                if(success) {
                    MainFrame.getMemoryData(MainFrame.memoryTable, MainFrame.mainMemories);
                    readyQueue[i] = queue.remove();
                    sort(readyQueue, 0, i);
                }
            }
        }
        return  Success;
    }

    /**
    * @Description: 判断ready队列是否已满，满时返回true
    * @Param: [readyQueue]
    * @return: boolean
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static boolean ReadyIsFull(PCB[] readyQueue){
        boolean FULL = true;
        for(int i = 0; i < readyQueue.length; i++){
            if(readyQueue[i]==null)
                FULL = false;
        }
        return FULL;
    }

    /**
    * @Description: 添加进程到new队列中
    * @Param: [Priority, timeRequired, memoryRequired, NewQueue]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void addProcess(int Priority, int timeRequired,int memoryRequired, Queue<PCB> NewQueue) {
        PCB pcb = new PCB();
        pcb.setStatus(1);
        List<PCB> PCBlist = PCBDAO.findAllPCB();
        PCB tmpPCB = PCBlist.get(PCBlist.size()-1);
        pcb.setId(tmpPCB.getId()+1);
        pcb.setPid("P"+(pcb.getId()));
        pcb.setPriority(Priority);
        pcb.setTimeRequired(timeRequired);
        pcb.setStorageRequierd(memoryRequired);
        PCBDAO.insertPCB(pcb);
        NewQueue.offer(pcb);
    }

    /**
    * @Description: 挂起进程
    * @Param: [Pid, suspendQueue, readyQueue, newQueue]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void suspend(String Pid, Queue<PCB> suspendQueue, PCB[] readyQueue, Queue<PCB> newQueue) {
        for (int i = 0; i < readyQueue.length; i++) {
            if (readyQueue[i] != null) {
                if (readyQueue[i].getPid().equals(Pid)) {
                    suspendQueue.offer(readyQueue[i]);
                    readyQueue[i] = newQueue.remove();
                }
            }
        }
    }

    /**
    * @Description: 解挂
    * @Param: [Pid, suspendQueue, newQueue]
    * @return: void
    * @Author: PY
    * @Date: 2021/11/26
    */
    public static void suspendCancel(String Pid, Queue<PCB> suspendQueue, Queue<PCB> newQueue) {
        PCB tmpPCB;
        while (!suspendQueue.peek().getPid().equals(Pid)) {  //遍历suspend队列来找到要解挂的进程
            tmpPCB = suspendQueue.remove();
            suspendQueue.offer(tmpPCB);
        }
        tmpPCB = suspendQueue.remove();
        StorageMethods.removeFromMemory(tmpPCB,MainFrame.mainMemories);
        newQueue.offer(tmpPCB);
        while(newQueue.peek()!=tmpPCB){
            PCB tmpPCB2 = newQueue.remove();
            newQueue.offer(tmpPCB2);
        }
    }
}
